package com.lemon.play.goai.posjudge.util;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class LinkedTree<T> implements Tree<T> {

	public LinkedTree() {
		this.current = head;
	}

	private void subTree0(LinkedTree<T> tree, Entry<T> c) {
		Entry<T> child = c.getChild();
		if (child != null) {
			tree.add(child.getElement());
			subTree0(tree, child);
		}
		tree.back();
		Entry<T> older = c.getOlder();
		if (older != null) {
			tree.add(older.getElement());
			subTree0(tree, older);
		}
	}

	public LinkedTree<T> removeEntryChildren(Entry<T> e) {
		e.setChild(null);
		return this;
	}

	public Entry<T> removeEntry(Entry<T> entry) {
		if (entry == head) {
			this.clear();
			return null;
		}
		Entry<T> parent = entry.getParent();
		Entry<T> older = entry.getOlder();
		Entry<T> younger = entry.getYounger();
		if (older != null)
			older.setYounger(younger);
		if (younger != null)
			younger.setOlder(older);
		else
			parent.setChild(older);
		return parent;
	}

	public LinkedTree<T> removeEntryBrothers(Entry<T> e) {
		if(e==head){
			return this;
		}
		Entry<T> parent = e.getParent();
		parent.setChild(e);
		e.setYounger(null);
		e.setOlder(null);
		return this;
	}

	private void postOrderTraversal(LinkedList<Entry<T>> list, Entry<T> root) {
		LinkedList<Entry<T>> children = this.getChildrenEntry(root);
		for (Entry<T> child : children) {
			this.postOrderTraversal(list, child);
		}
		list.add(root);
	}
	
	public int getYoungerCount(Entry<T> e){
		if(e==null){
			throw new NullPointerException("Param cannot be null!");
		}
		int count=0;
		Entry<T> c=e.getYounger();
		while(c!=null){
			count++;
			c=c.getYounger();
		}
		return count;
	}
	
	public int getOlderCount(Entry<T> e){
		if(e==null){
			throw new NullPointerException("Param cannot be null!");
		}
		int count=0;
		Entry<T> c=e.getOlder();
		while(c!=null){
			count++;
			c=c.getOlder();
		}
		return count;
	}

	private int getTreeDepth(Entry<T> c) {
		int depth = 0;
		Entry<T> child = c.getChild();
		if (child != null) {
			depth = getTreeDepth(child)+1;
		}
		Entry<T> older = c.getOlder();
		if (older != null) {
			int depth2 = getTreeDepth(older);
			depth = depth > depth2 ? depth : depth2;
		}
		return depth;
	}
	
	public LinkedList<Entry<T>> getPathEntry(Entry<T> e){
		LinkedList<Entry<T>> list=new LinkedList<Entry<T>>();
		Entry<T> c=e;
		while(c!=null){
			list.addFirst(c);
			c=c.getParent();
		}
		return list;
	}
	
	public LinkedList<Entry<T>> getPathEntry(){
		return this.getPathEntry(current);
	}
	
	@Override
	public List<T> getPath(T e){
		Entry<T> entry=this.getElementEntry(e, head);
		if(entry==null)
			throw new IllegalArgumentException("Cannot find the element!");
		LinkedList<Entry<T>> list=this.getPathEntry(entry);
		list.removeFirst();
		LinkedList<T> result=new LinkedList<T>();
		for(int i=0;i<list.size();i++){
			result.add(list.get(0).getElement());
		}
		return result;
	}
	
	@Override
	public List<T> getPath(){
		LinkedList<Entry<T>> list=this.getPathEntry();
		list.removeFirst();
		LinkedList<T> result=new LinkedList<T>();
		for(Entry<T> e:list){
			result.add(e.getElement());
		}
		return result;
	}

	public int getEntryDepth(Entry<T> e) {
		int count = 0;
		Entry<T> parent = e.getParent();
		while (parent != null) {
			parent = parent.getParent();
			count++;
		}
		return count;
	}

	public LinkedList<Entry<T>> getBrothersEntry(Entry<T> e) {
		LinkedList<Entry<T>> list = new LinkedList<Entry<T>>();
		Entry<T> c = e.getOlder();
		while (c != null) {
			list.add(c);
			c = c.getOlder();
		}
		c = e.getYounger();
		while (c != null) {
			list.add(c);
			c = c.getYounger();
		}
		return list;
	}

	public LinkedList<Entry<T>> getChildrenEntry(Entry<T> e) {
		LinkedList<Entry<T>> children = new LinkedList<Entry<T>>();
		Entry<T> child = e.getChild();
		while (child != null) {
			children.add(child);
			child = child.getOlder();
		}
		return children;
	}

	public List<T> getChildren(Entry<T> e) {
		LinkedList<T> children = new LinkedList<T>();
		Entry<T> child = e.getChild();
		while (child != null) {
			children.add(child.getElement());
			child = child.getOlder();
		}
		return children;
	}

	public Entry<T> getElementEntry(T e, Entry<T> root) {
		Entry<T> child = root.getChild();
		if (child != null) {
			if (child.getElement().equals(e))
				return child;
			Entry<T> result = getElementEntry(e, child);

			if (result != null)
				return result;
		}
		Entry<T> older = root.getOlder();
		if (older != null) {
			if (older.getElement().equals(e))
				return older;
			return getElementEntry(e, older);
		}
		return null;
	}

	public LinkedTree<T> cutEntry(Entry<T> e) {
		LinkedList<Entry<T>> children = this.getChildrenEntry(e);
		Entry<T> parent = e.getParent();
		this.removeEntry(e);
		e = parent;
		Entry<T> older = parent.getOlder();
		for (Entry<T> child : children) {
			child.setParent(parent);
			child.setOlder(older);
			if (older != null)
				older.setYounger(child);
			parent.setChild(child);
			older = child;
		}
		return this;
	}

	private void breadthFirstTraversal(int depth,
			LinkedList<LinkedList<Entry<T>>> list, Entry<T> root) {
		if (depth > list.size()) {
			list.set(depth, new LinkedList<Entry<T>>());
		}
		LinkedList<Entry<T>> children = this.getChildrenEntry(root);
		LinkedList<Entry<T>> layer = list.get(depth);
		depth++;
		for (Entry<T> child : children) {
			layer.add(child);
			this.breadthFirstTraversal(depth, list, child);
		}
	}

	private void addTree(Tree<T> tree) {
		List<T> children = tree.getChildren();
		for (T child : children) {
			add(child);
			tree.setCurrentInChildren(child);
			addTree(tree);
		}
		back();
		tree.back();
	}

	@Override
	public Tree<T> subTree() {
		LinkedTree<T> sub = new LinkedTree<T>();
		if (current != head)
			sub.add(current.getElement());
		subTree0(sub, current);
		return sub;
	}

	@Override
	public Tree<T> setCurrentInWhole(T e) {
		Entry<T> result = this.getElementEntry(e, head);
		if (result != null)
			current = result;
		return this;
	}

	@Override
	public Tree<T> setCurrentInChildren(T e) {
		LinkedList<Entry<T>> list = this.getChildrenEntry(current);
		boolean flag = true;
		for (Entry<T> entry : list) {
			if (entry.getElement().equals(e)) {
				current = entry;
				flag = false;
				break;
			}
		}
		if (flag) {
			throw new IllegalArgumentException(
					"Cannot find the element in current children");
		}
		return this;
	}

	@Override
	public Tree<T> setCurrentInChildren(int index) {
		LinkedList<Entry<T>> children = this.getChildrenEntry(current);
		if (index >= children.size()) {
			throw new IllegalArgumentException(
					"Cannot find element of this index in children!");
		}
		Entry<T> child = children.get(index);
		current = child;
		return this;
	}

	@Override
	public Tree<T> setCurrentInBrother(T e) {
		LinkedList<Entry<T>> list = this.getBrothersEntry(current);
		boolean flag = true;
		for (Entry<T> entry : list) {
			if (entry.getElement().equals(e)) {
				current = entry;
				flag = false;
				break;
			}
		}
		if (flag) {
			throw new IllegalArgumentException(
					"Cannot find the element in current brothers");
		}
		return this;
	}
	
	public Tree<T> setCurrentEntry(Entry<T> current){
		if(current==null)
			throw new NullPointerException("Param must be non-null");
		this.current=current;
		return this;
	}

	@Override
	public Tree<T> removeInWhole(T e) {
		Entry<T> c = this.getElementEntry(e, head);
		this.removeEntry(c);
		return null;
	}

	@Override
	public Tree<T> removeParent() {
		if (current == head)
			throw new IllegalStateException("Don't have parent");
		return this;
	}

	@Override
	public Tree<T> removeChildren() {
		this.removeEntryChildren(current);
		return this;
	}

	@Override
	public Tree<T> removeChild(int index) {
		LinkedList<Entry<T>> children = this.getChildrenEntry(current);
		if(index>children.size()){
			throw new NullPointerException("Don't have enough children!");
		}
		Entry<T> child = children.get(index);
		this.removeEntry(child);
		return this;
	}

	@Override
	public Tree<T> removeChild(T e) {
		LinkedList<Entry<T>> list = this.getChildrenEntry(current);
		for (Entry<T> entry : list) {
			if (entry.getElement().equals(e)) {
				removeEntry(entry);
				break;
			}
		}
		return this;
	}

	@Override
	public Tree<T> removeBrothers() {
		removeEntryBrothers(current);
		return this;
	}

	@Override
	public Tree<T> removeBrother(T e) {
		LinkedList<Entry<T>> list = this.getBrothersEntry(current);
		for (Entry<T> b : list) {
			if (b.getElement().equals(e)) {
				removeEntry(b);
				break;
			}
		}
		return this;
	}

	@Override
	public Tree<T> remove() {
		Entry<T> e = removeEntry(current);
		if (e == null)
			return null;
		current = e;
		return this;
	}

	@Override
	public boolean isLeaf() {
		return current.getChild() == null;
	}

	@Override
	public boolean isLeaf(T e) {
		Entry<T> entry = this.getElementEntry(e, head);
		return entry.getChild() == null;
	}

	@Override
	public Enumeration<T> getDepthFirstTraversal() {
		LinkedList<Entry<T>> list = new LinkedList<Entry<T>>();
		this.postOrderTraversal(list, head);
		list.removeLast();
		ArrayList<T> data = new ArrayList<T>(list.size());
		for (Entry<T> e : list) {
			data.add(e.getElement());
		}
		TreeEnumeration<T> enumer = new TreeEnumeration<T>(data);
		return enumer;
	}

	@Override
	public Enumeration<T> getBreadthFirstTraversal() {
		LinkedList<LinkedList<Entry<T>>> list = new LinkedList<LinkedList<Entry<T>>>();
		this.breadthFirstTraversal(0, list, head);
		int length = 0;
		for (LinkedList<Entry<T>> l : list) {
			length += l.size();
		}
		ArrayList<T> data = new ArrayList<T>(length);
		for (LinkedList<Entry<T>> l : list) {
			for (Entry<T> entry : l) {
				data.add(entry.getElement());
			}
		}
		Enumeration<T> e = new TreeEnumeration<T>(data);
		return e;
	}

	@Override
	public Iterator<T> iterator() {
		TreeIterator<T> iter = new TreeIterator<T>(this);
		return iter;
	}

	@Override
	public Tree<T> insert(T e) {
		Entry<T> parent = current.parent;
		Entry<T> n = new Entry<T>(e, null, null, current, parent);
		parent.setChild(n);
		current.setParent(n);
		current = n;
		return this;
	}

	@Override
	public int getTreeDepth() {
		return getTreeDepth(head);
	}

	@Override
	public int getDepth(T e) {
		Entry<T> entry = this.getElementEntry(e, head);
		if (entry == null) {
			throw new IllegalArgumentException("Cannot find the element!");
		}
		return this.getEntryDepth(entry);
	}

	@Override
	public int getDepth() {
		return this.getEntryDepth(current);
	}

	@Override
	public List<T> getChildren(T e) {
		Entry<T> entry = this.getElementEntry(e, head);
		if (entry == null)
			throw new IllegalArgumentException(
					"Cannot find the element in the tree!");
		return this.getChildren(entry);
	}

	@Override
	public List<T> getChildren() {
		return this.getChildren(current);
	}

	@Override
	public List<T> getBrothers() {
		LinkedList<T> brothers = new LinkedList<T>();
		LinkedList<Entry<T>> list = this.getBrothersEntry(current);
		for (Entry<T> e : list) {
			brothers.add(e.getElement());
		}
		return brothers;
	}

	@Override
	public T getCurrent() {
		return current.getElement();
	}

	@Override
	public T getParent() {
		return current.getParent().getElement();
	}

	@Override
	public T getAncester(int index) {
		if (current == head)
			throw new IllegalStateException("Ancester don't exist!");
		Entry<T> ancester = current;
		for (int i = 0; i < index; i++) {
			ancester = current.getParent();
			if (ancester == head) {
				throw new IllegalArgumentException("The ancester don't exist!");
			}
		}
		return ancester.getElement();
	}

	@Override
	public Tree<T> cutInWhole(T e) {
		Entry<T> entry = this.getElementEntry(e, head);
		if (entry == null) {
			throw new IllegalArgumentException(
					"Cannot find the element in whole tree!");
		}
		this.cutEntry(entry);
		return this;
	}

	@Override
	public Tree<T> cutInChildren(T e) {
		LinkedList<Entry<T>> children = this.getChildrenEntry(current);
		boolean flag = true;
		for (Entry<T> child : children) {
			if (child.getElement().equals(e)) {
				this.cutEntry(child);
				flag = false;
				break;
			}
		}
		if (flag) {
			throw new IllegalArgumentException(
					"The tree don't contain this element!");
		}
		return this;
	}

	@Override
	public Tree<T> cutInBrothers(T e) {
		LinkedList<Entry<T>> brothers = this.getBrothersEntry(current);
		boolean flag = true;
		for (Entry<T> brother : brothers) {
			if (brother.getElement().equals(e)) {
				this.cutEntry(brother);
				flag = false;
				break;
			}
		}
		if (flag) {
			throw new IllegalArgumentException(
					"The tree don't contain this element!");
		}
		return this;
	}

	@Override
	public Tree<T> cut() {
		if (current == head) {
			throw new IllegalStateException(
					"The root of tree cannot be cutten!");
		}
		this.cutEntry(current);
		current = current.getParent();
		return this;
	}

	@Override
	public Tree<T> clear() {
		head = new Entry<T>(null, null, null, null, null);
		current = head;
		return this;
	}

	@Override
	public Tree<T> backToHead() {
		current = head;
		return this;
	}

	@Override
	public Tree<T> back() {
		if (current == head) {
			throw new IllegalStateException("The tree is already back to root!");
		}
		current = current.getParent();
		return this;
	}

	@Override
	public Tree<T> add(Tree<T> tree) {
		T c = tree.getCurrent();
		tree.backToHead();
		addTree(tree);
		tree.setCurrentInWhole(c);
		return this;
	}

	@Override
	public Tree<T> add(T e) {
		if (e == null) {
			throw new NullPointerException("The param cannot be null!");
		}
		Entry<T> older = current.getChild();
		Entry<T> n = new Entry<T>(e, null, older, null, current);
		if (older != null) {
			older.setYounger(n);
		}
		current.setChild(n);
		current = n;
		return this;
	}

	public Entry<T> getHeadEntry() {
//		return new UneditableEntry<T>(head);
		return head;
	}

	public Entry<T> getCurrentEntry() {
//		return new UneditableEntry<T>(current);
		return current;
	}

	private void getLayerEntry(LinkedList<Entry<T>> list, int same, Entry<T> c) {
		if (same == 0) {
			Entry<T> older = c;
			while (c != null) {
				list.add(older);
				older = older.getOlder();
			}
			return;
		}
		Entry<T> child = c.getChild();
		if (child != null) {
			getLayerEntry(list, same - 1, child);
		}
		Entry<T> older = c.getOlder();
		if (older != null) {
			getLayerEntry(list, same, older);
		}
	}

	public LinkedList<Entry<T>> getLayerEntry(int depth) {
		LinkedList<Entry<T>> list = new LinkedList<Entry<T>>();
		getLayerEntry(list, depth, head);
		return list;
	}

	public Tree<T> setCurrentInLayer(int index, int depth) {
		LinkedList<Entry<T>> list = this.getLayerEntry(this.getDepth());
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					"There is no layer in this depth!");
		} else if (index >= list.size()) {
			throw new IllegalArgumentException(
					"Cannot find element in this index of the layer depth elements!");
		}
		Entry<T> e = list.get(index);
		current = e;
		return this;
	}

	public Tree<T> setCurrentInLayer(T e, int depth) {
		LinkedList<Entry<T>> list = this.getLayerEntry(this.getDepth());
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					"There is no layer in this depth!");
		}
		boolean flag = true;
		for (Entry<T> entry : list) {
			if (entry.getElement().equals(e)) {
				current = entry;
				flag = false;
				break;
			}
		}
		if (flag) {
			throw new IllegalArgumentException(
					"Cannot find the element in this layer depth!");
		}
		return this;
	}

	public Tree<T> setCurrentInLayer(T e) {
		return this.setCurrentInLayer(e, this.getDepth());
	}

	public LinkedTree<T> removeInLayer(int depth, T e) {
		LinkedList<Entry<T>> list = this.getLayerEntry(depth);
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					"There is no layer in this depth!");
		}
		for (Entry<T> entry : list) {
			if (entry.getElement().equals(e)) {
				removeEntry(entry);
				break;
			}
		}
		return this;
	}

	public LinkedTree<T> removeLayer(int depth) {
		Entry<T> c = current;
		int currentDepth = this.getEntryDepth(c);
		this.backToHead();
		LinkedList<Entry<T>> list = this.getLayerEntry(depth);
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					"There is no layer in this depth!");
		}
		for (Entry<T> e : list) {
			removeEntry(e);
		}
		if (currentDepth < depth) {
			current = c;
		}
		return this;
	}

	public LinkedTree<T> removeInLayer(T e) {
		return this.removeInLayer(this.getDepth(), e);
	}

	public LinkedTree<T> layerTree(int depth) {
		LinkedTree<T> tree = new LinkedTree<T>();
		LinkedList<Entry<T>> list = getLayerEntry(depth);
		if (list.size() == 0) {
			throw new IllegalArgumentException(
					"There is no layer in this depth!");
		}
		for (Entry<T> e : list) {
			tree.add(e.getElement());
			subTree0(tree, e);
			tree.backToHead();
		}
		return tree;
	}

	public List<T> getLayer(int depth) {
		LinkedList<Entry<T>> list = this.getLayerEntry(depth);
		LinkedList<T> aspect = new LinkedList<T>();
		for (Entry<T> e : list) {
			aspect.add(e.getElement());
		}
		return aspect;
	}

	public List<T> getLayer() {
		return getLayer(this.getDepth());
	}

	private Entry<T> current = null;
	private Entry<T> head = new RootEntry<T>();

	public static class Entry<T> {
		private T element;
		private Entry<T> older;
		private Entry<T> younger;
		private Entry<T> child;
		private Entry<T> parent;

		public T getElement() {
			return element;
		}

		public Entry<T> getOlder() {
			return older;
		}

		public void setOlder(Entry<T> older) {
			this.older = older;
		}

		public Entry<T> getYounger() {
			return younger;
		}

		public void setYounger(Entry<T> younger) {
			this.younger = younger;
		}

		public void setElement(T element) {
			this.element = element;
		}

		public Entry<T> getChild() {
			return child;
		}

		public void setChild(Entry<T> child) {
			this.child = child;
		}

		public Entry<T> getParent() {
			return parent;
		}

		public void setParent(Entry<T> parent) {
			this.parent = parent;
		}

		public Entry(T element, Entry<T> younger, Entry<T> older,
				Entry<T> child, Entry<T> parent) {
			this.element = element;
			this.older = older;
			this.younger = younger;
			this.child = child;
			this.parent = parent;
		}

		@Override
		public boolean equals(Object o) {
			if(o==null)
				return false;
			if (o instanceof Entry) {
				Object e = ((Entry) o).getElement();
				if (element == null) {
					if (e == null){
						return true;
					}
					else{
						return false;
					}
				}
				return element.equals(e);
			}
			return false;
		}
		
		@Override
		public String toString(){
			if(element==null){
				return "null";
			}
			return element.toString();
		}

	}
	
	private static final class RootEntry<T> extends Entry<T> {

		public RootEntry() {
			super(null, null, null, null, null);
		}

		@Override
		public void setElement(T element) {
			throw new IllegalStateException("Cannot set element for root!");
		}

		@Override
		public void setOlder(Entry<T> older) {
			throw new IllegalStateException("Cannot set older for root!");
		}

		@Override
		public void setParent(Entry<T> parent) {
			throw new IllegalStateException("Cannot set parent for root!");
		}

		@Override
		public void setYounger(Entry<T> younger) {
			throw new IllegalStateException("Cannot set younger for root!");
		}
		
		@Override
		public boolean equals(Object o){
			if(o==null)
				return false;
			if(!(o instanceof Entry))
				return false;
			Entry e=(Entry) o;
			if(e.getElement()==null){
				return true;
			}
			return false;
		}
	}

//	private static final class UneditableEntry<T> extends Entry<T> {
//
//		public UneditableEntry(Entry<T> source) {
//			super(source.getElement(), source.getYounger(), source.getOlder(),
//					source.getChild(), source.getParent());
//		}
//
//		@Override
//		public Entry<T> getChild() {
//			Entry<T> child = super.getChild();
//			if (child == null)
//				return null;
//			else if (!child.getClass().equals(UneditableEntry.class)) {
//				super.setChild(new UneditableEntry<T>(child));
//			}
//			return super.getChild();
//		}
//
//		@Override
//		public Entry<T> getOlder() {
//			Entry<T> older = super.getOlder();
//			if (older == null)
//				return null;
//			else if (!older.getClass().equals(UneditableEntry.class)) {
//				super.setOlder(new UneditableEntry<T>(older));
//			}
//			return super.getOlder();
//		}
//
//		@Override
//		public Entry<T> getParent() {
//			Entry<T> parent = super.getParent();
//			if (parent == null)
//				return null;
//			else if (!parent.getClass().equals(UneditableEntry.class)) {
//				super.setParent(new UneditableEntry<T>(parent));
//			}
//			return super.getParent();
//		}
//
//		@Override
//		public Entry<T> getYounger() {
//			Entry<T> younger = super.getYounger();
//			if (younger == null)
//				return null;
//			else if (!younger.getClass().equals(UneditableEntry.class)) {
//				super.setYounger(new UneditableEntry<T>(younger));
//			}
//			return super.getYounger();
//		}
//
//		@Override
//		public void setElement(T e) {
//			return;
//		}
//
//		@Override
//		public void setYounger(Entry<T> e) {
//			return;
//		}
//
//		@Override
//		public void setOlder(Entry<T> e) {
//			return;
//		}
//
//		@Override
//		public void setChild(Entry<T> e) {
//			return;
//		}
//
//		@Override
//		public void setParent(Entry<T> e) {
//			return;
//		}
//	}

	private static final class TreeIterator<T> implements Iterator<T> {

		public TreeIterator(LinkedTree<T> tree) {
			this.tree = tree;
			this.current = tree.head;
			this.previous = null;
			checked = false;
		}

		@Override
		public boolean hasNext() {
			checked = true;
			if (current == null)
				return false;
			this.previous = current;
			boolean flag = checkNext();
			return flag;
		}

		private boolean checkNext() {
			if (hasChild()) {
				current = current.getChild();
				return true;
			}
			if (hasOlder()) {
				current = current.getOlder();
				return true;
			}
			if (hasUncle()) {
				current = current.getParent().getOlder();
				return true;
			}
			current = null;
			return false;
		}

		private boolean hasChild() {
			if (current.getChild() == null)
				return false;
			return true;
		}

		private boolean hasOlder() {
			if (current.getOlder() == null)
				return false;
			return true;
		}

		private boolean hasUncle() {
			if (current.getParent() == null)
				return false;
			if (current.getParent().getOlder() == null)
				return false;
			return true;
		}

		@Override
		public T next() {
			if (!checked) {
				hasNext();
			}
			checked = false;
			if (current == null)
				throw new IllegalStateException("There is no next element!");
			return current.getElement();
		}

		@Override
		public void remove() {
			if (current == null) {
				throw new IllegalStateException(
						"There is no element to remove!");
			}
			tree.removeEntry(current);
			current = this.previous;
		}

		private LinkedTree<T> tree;
		private Entry<T> current;
		private Entry<T> previous;
		private boolean checked;
	}

	private static final class TreeEnumeration<T> implements Enumeration<T> {

		public TreeEnumeration(ArrayList<T> data) {
			this.data = data;
		}

		@Override
		public boolean hasMoreElements() {
			if (point < data.size())
				return true;
			return false;
		}

		@Override
		public T nextElement() {
			return data.get(point++);
		}

		private ArrayList<T> data;
		private int point = 0;
	}
}
